﻿using System;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using EPiServer;
using EPiServer.ClientScript;
using EPiServer.ClientScript.Events;
using EPiServer.ClientScript.WebControls;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.Globalization;
using EPiServer.UI;
using EPiServer.UI.WebControls;
using EPiServer.Web.PageExtensions;
using FilteredPageReference.UserControls;

namespace FilteredPageReference.Pages
{
    public class PageBrowserFilteredPageReference : SystemPageBase
    {
        // Fields
        private string _infoVariable;
        private string _valueVariable;
        protected TabStrip browserActionTab;
        protected Panel browserTabView;
        protected ToolButton cancelButton;
        protected Tab Favorites;
        protected Panel FavoriteViewPanel;
        protected PageExplorerFilteredPageReference favouritesTreeView;
        protected Label Label1;
        protected ToolButton nothingButton;
        protected ToolButton okButton;
        protected PageExplorerFilteredPageReference pageTreeView;
        protected ScriptEvent ScriptEvent1;
        protected ToolButton searchButton;
        protected TextBox searchKey;
        protected HtmlInputHidden selectedPageLink;
        protected HtmlInputHidden selectedPageName;
        protected ToolButton selfButton;
        protected Tab Structure;
        protected Panel TreeViewPanel;
        protected PageReference PageLink = PageReference.EmptyReference;
        protected Panel Panel2;
        protected Panel Panel3;
        protected PlaceHolder InvalidPagePlaceHolder;
        protected PlaceHolder InvalidPagePlaceHolder2;
        protected PlaceHolder MainFormPlaceHolder;
        protected PlaceHolder SessionExpiredPlaceHolder;
        protected PlaceHolder SessionExpiredPlaceHolder2;
        protected string CallBackFunctionName = string.Empty;

        protected PropertyFilteredPageReferenceSettings _settings;

        // Methods
        public PageBrowserFilteredPageReference()
            : base(0, SiteRedirect.OptionFlag)
        {
        }

        protected string FPRData
        {
            get
            {
                return Server.UrlDecode(Request.QueryString["fprdata"]);
            }
        }

        protected string FPRKey
        {
            get { return Request.QueryString["fprkey"]; }
        }

        protected PropertyFilteredPageReferenceSettings Settings
        {
            get
            {
                if (_settings == null)
                    _settings = Helper.GetPropertySettings(FPRData, FPRKey);

                return _settings;
            }
        }

        protected void actionTab_TabClicked(object sender, EventArgs e)
        {
            if (this.browserActionTab.SelectedTab == 0)
            {
                this.pageTreeView.DataBind();
            }
            else if (this.browserActionTab.SelectedTab == 1)
            {
                this.favouritesTreeView.DataBind();
            }
        }

        private void HandleSearch()
        {
            PageReference emptyReference;
            string text = this.searchKey.Text;
            try
            {
                emptyReference = PageReference.Parse(text);
            }
            catch
            {
                emptyReference = PageReference.EmptyReference;
            }
            if (PageReference.IsNullOrEmpty(emptyReference))
            {
                emptyReference = new SearchPages().FindByName(text, ContentLanguage.PreferredCulture.Name);
            }
            else
            {
                try
                {
                    DataFactory.Instance.GetPage(emptyReference);
                }
                catch
                {
                    emptyReference = PageReference.EmptyReference;
                }
            }

            if (!PageReference.IsNullOrEmpty(emptyReference))
            {
                bool validPage = true;
                bool valid = false;
                emptyReference.WorkID = 0;
                string pageName = DataFactory.Instance.GetPage(emptyReference).PageName;
                PageData page = DataFactory.Instance.GetPage(emptyReference);
                PropertyInformation propertyInformation = Helper.GetPropertyInformation(FPRData, ref valid);

                if (!Helper.IsValidPageType(page.PageTypeID, Settings, propertyInformation))
                {
                    PropertyData propertyData = DataFactory.Instance.GetDefaultPageData(PageReference.StartPage, propertyInformation.PageTypeId).Property[propertyInformation.PropertyName];                   
                    validPage = false;

                    string validationErrorMessage = string.Empty;
                    string allowedPageTypes = string.Empty;

                    if (!string.IsNullOrEmpty(Settings.ValidationErrorMessage))
                        validationErrorMessage = Settings.ValidationErrorMessage;
                    else
                        allowedPageTypes = Helper.GetCommaDelimitedListOfAllowedPageTypes(Settings.PageTypeNames, Settings.FullTypeNames);

                    if (string.IsNullOrEmpty(validationErrorMessage))
                    {

                        if (!string.IsNullOrEmpty(allowedPageTypes))
                        {
                            validationErrorMessage = string.Format(LanguageHelper.Translate("/filteredPageReference/pageTypesWithValidPageTypesMessage"),
                                pageName, propertyData.TranslateDisplayName(), allowedPageTypes);
                        }
                        else
                        {
                            validationErrorMessage = string.Format(LanguageHelper.Translate("/filteredPageReference/pageIsNotValidMessage"),
                                pageName, propertyData.TranslateDisplayName());
                        }
                    }

                    base.ScriptManager.AddEventListener(Page, new AlertEvent(EventType.Load, validationErrorMessage));
                }
                else
                {
                    PageReference startPageLink = Helper.GetPagePickingStartPage(Settings, FPRData);
                    
                    if (!PageReference.IsNullOrEmpty(startPageLink) && !Helper.IsDescendent(startPageLink, page))
                    {
                        validPage = false;
                        PageData startPage = DataFactory.Instance.GetPage(startPageLink);


                        string validationErrorMessage = string.Format(LanguageHelper.Translate("/filteredPageReference/pageIsNotADescendant"),
                            pageName, startPage.PageName, startPage.PageLink.ID);

                        base.ScriptManager.AddEventListener(Page, new AlertEvent(EventType.Load, validationErrorMessage));
                    }
                }

                if (validPage)
                {
                    base.ScriptManager.AddEventListener(this.Page, new CustomEvent(EventType.Load, string.Format("function(){{ SetLocalValues(\"{0}\",\"{1}\"); }}", emptyReference, ClientScriptUtility.ToScriptSafeString(pageName))));
                    this.selectedPageName.Value = pageName;
                    this.selectedPageLink.Value = emptyReference.ToString();
                    this.SelectedPageViewPath = emptyReference.ToString();
                    this.SetSelectedPageInTree(this.SelectedPageViewPath);
                    if (this.browserActionTab.SelectedTab == 0)
                    {
                        this.pageTreeView.DataBind();
                    }
                    else if (this.browserActionTab.SelectedTab == 1)
                    {
                        this.favouritesTreeView.DataBind();
                    }
                }
            }
            else
            {
                base.ScriptManager.AddEventListener(this.Page, new AlertEvent(EventType.Load, base.Translate("/system/pagebrowser/notfound")));
            }
        }

        protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);
            Page.MasterPageFile = EPiServer.Configuration.Settings.Instance.UIUrl + "MasterPages/EPiServerUI.Master";
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            bool valid = true;
            CallBackFunctionName = string.Format("fprQuickEditing_{0}_Changed", Helper.GetPropertyInformation(FPRData, ref valid).PropertyName.Trim());
            MainFormPlaceHolder.Visible = true;
            InvalidPagePlaceHolder.Visible = false;
            InvalidPagePlaceHolder2.Visible = false;
            SessionExpiredPlaceHolder.Visible = false;
            SessionExpiredPlaceHolder2.Visible = false;

            if (Settings.StartFromCurrentPage && String.IsNullOrEmpty(Settings.CurrentPageId))
            {
                InvalidPagePlaceHolder.Visible = true;
                InvalidPagePlaceHolder2.Visible = true;
                return;
            }

            if (!string.IsNullOrEmpty(FPRKey) && Session[FPRKey] == null)
            {
                SessionExpiredPlaceHolder.Visible = true;
                SessionExpiredPlaceHolder2.Visible = true;
                return;
            }

            // load page explorer controls
            pageTreeView = Page.LoadControl("~/util/FilteredPageReference/PageExplorerFilteredPageReference.ascx") as PageExplorerFilteredPageReference;
            pageTreeView.DisplayTreeMode = PageExplorerFilteredPageReference.TreeMode.ExplorerTree;
            pageTreeView.ExpandDepth = 1;
            pageTreeView.ExpandOnSelect = false;
            pageTreeView.EnableDragAndDrop = false;
            pageTreeView.ClientInitializationCallback = "initPageTreeView";
            Panel2.Controls.Add(pageTreeView);

            favouritesTreeView = Page.LoadControl("~/util/FilteredPageReference/PageExplorerFilteredPageReference.ascx") as PageExplorerFilteredPageReference;
            favouritesTreeView.DisplayTreeMode = PageExplorerFilteredPageReference.TreeMode.FavouritesTree;
            favouritesTreeView.ExpandDepth = 0;
            favouritesTreeView.ExpandOnSelect = false;
            favouritesTreeView.EnableDragAndDrop = false;
            favouritesTreeView.ClientInitializationCallback = "initPageTreeView";
            Panel3.Controls.Add(favouritesTreeView);

            this.Page.Form.DefaultButton = this.searchButton.UniqueID;
            ThemeUtility.RegisterThemeCss(this.Page, "pagetreeview.css");

            PageLink = CurrentPageLink;
            string queryString = Server.UrlDecode(Request.QueryString.ToString());

            if (queryString.Contains("?id="))
            {
                queryString = queryString.Substring(queryString.IndexOf("?id=") + 4);
                queryString = queryString.Substring(0, queryString.IndexOf("&"));

                if (!string.IsNullOrEmpty(queryString) && queryString != "-")
                    PageLink = PageReference.Parse(queryString);
            }


            if (!base.IsPostBack)
            {
                if (PageLink.Equals(PageReference.SelfReference))
                {
                    this.SelectedPageViewPath = PageReference.EmptyReference.ToString();
                }
                else
                {
                    this.SelectedPageViewPath = PageLink.ToString();
                }
                this.selectedPageLink.Value = PageLink.ToString();

                PageData page = CurrentPage;

                if (!PageReference.IsNullOrEmpty(PageLink))
                    page = DataFactory.Instance.GetPage(PageLink);

                this.selectedPageName.Value = (page != null) ? page.PageName : string.Empty;
            }
            this.SetSelectedPageInTree(this.SelectedPageViewPath);
            
            base.Title = LanguageManager.Instance.Translate("/system/pagebrowser/heading");
            this._valueVariable = base.Request.QueryString["value"];
            this._infoVariable = base.Request.QueryString["info"];
            this.selfButton.Enabled = string.Compare(base.Request.QueryString["disablecurrentpageoption"], "true", true) != 0;
            if (string.Compare(base.Request.QueryString["displaywarning"], "true", true) == 0)
            {
                base.ScriptManager.AddEventListener(this.Page, new AlertEvent(EventType.Load, LanguageManager.Instance.Translate("/system/pagebrowser/noaccesswarning")));
            }

            if (!string.IsNullOrEmpty(selectedPageLink.Value))
            {
                PageData page = DataFactory.Instance.GetPage(PageReference.Parse(selectedPageLink.Value));

                if (!Helper.IsValidPageType(page.PageTypeID, Settings, Helper.GetPropertyInformation(FPRData, ref valid)))
                {
                    selectedPageLink.Value = string.Empty;
                    selectedPageName.Value = string.Empty;
                }
            }
        }

        protected void searchButton_Click(object sender, EventArgs e)
        {
            this.HandleSearch();
            base.ScriptManager.AddEventListener(this.Page, new SetFocusEvent(EventType.Load, this.searchKey.ClientID));
        }

        private void SetSelectedPageInTree(string viewPath)
        {
            this.pageTreeView.SelectedNodeViewPath = viewPath;
            this.favouritesTreeView.SelectedNodeViewPath = viewPath;
        }

        // Properties
        protected string InfoVariable
        {
            get
            {
                return this._infoVariable;
            }
            set
            {
                this._infoVariable = value;
            }
        }

        protected static PageReference RootPage
        {
            get
            {
                return PageReference.RootPage;
            }
        }

        protected string SelectedPageViewPath
        {
            get
            {
                return (this.ViewState["SelectedPageViewPath"] == null ? this.PageLink.ToString() : ViewState["SelectedPageViewPath"].ToString());
            }
            set
            {
                this.ViewState["SelectedPageViewPath"] = value;
            }
        }

        protected string ValueVariable
        {
            get
            {
                return this._valueVariable;
            }
            set
            {
                this._valueVariable = value;
            }
        }
    }
}
 
